<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../js/vue.js"></script>
</head>
<body>
    <!-- 根组件 -->
    <div id="app">
        <p>count:{{count}}</p>
        <p><button @click="count++">count++</button></p>

        <hr>
        <button @click="isShow=!isShow">switch</button>
        <laowang-clock v-if="isShow"></laowang-clock>



    </div>
    <!-- 
        var vNode1 = {
                tag:"div",  // 标签名
                attrs:{    // 属性
                    id:"#app",
                },
                elm: div#app,  // 对应的真实DOM/文本节点
                text:"",    // 如果是文本节点 => 存文本内容
                children:[  // 子节点
                    {tag:"p",attrs:{},elm:p, text:"", children:[{ tag:"", attrs:{}, elm:TextNode, text:"hello world" }]}
                    {tag:"p",attrs:{},elm:p, text:"", children:[]}
                    {tag:"laowang-clock",attrs:{},elm:div.show-time, text:"", children:[]}
                   
                ]
           }

     -->
</body>
<script>
    /*  
        !!! 在Vue中,每一个组件都是一个vue实例, 有自己的配置项(data methods template computed watch 生命周期钩子)    

        Vue中如何定义组件?  

        1.  全局组件  => 一次注册,多次使用
            Vue.component(componentName,option)
                componentName  组件名称(字符串)
                    组件名称推荐使用, 中划线命名法 和 大驼峰命名法
                        中划线命名法:  laowang-clock
                        大驼峰命名法:  LaowangClock


                option 组件相关配置 (包含data methods computed watch 生命周期钩子)   


            优点:
                一次注册,多次使用(任何位置)

            缺点:

    



        2.  局部组件


        Vue中如何使用组件?
            1. 对应组件名称, 在需要使用组件的组件, 创建自定义标签   => 该自定义标签,会在组件挂载时, 替换为template中的元素
            2. Vue2中, 组件命名时,可以使用 中划线命名法 和 大驼峰命名法, 但是组件使用时推荐使用 中划线命名法


        组件之间的层级关系
            根组件  父组件 子组件  兄弟组件

        组件注册注意:
            1. 在Vue中,每一个组件都是一个vue实例, 有自己的配置项(data methods template computed watch 生命周期钩子)   
            2. data选项要求是一个返回对象的函数
            3. 单个根元素 (组件的模板只能有一个根元素 => Vue2要求,  Vue3无所谓)


        Vue组件的生命周期(创建和挂载)
            1. 首先根(父)组件先进行初始化渲染(生命周期开始), 解析根(父)组件的option配置对象, 在将模板解析为虚拟DOM, 解析过程中遇到自定义标签(a. 用户随便定义的标签 b. 用户定义的组价), 如果确认是组件, 根(父)组件解析工作暂停, 开始子组件的初始化渲染阶段, 子组件也要解析配置对象,也要将模板解析为虚拟DOM, 在渲染为真实DOM, 将解析的真实DOM,将真实DOM存储到父组件的虚拟DOM解析数据中,  子组件解析完毕, 根(父)组件解析工作继续, 直到所有内容解析完毕, 在将根(父)组件的虚拟DOM渲染为真实DOM, 更新视图


         Vue组件的生命周期(更新阶段)
            (1) 组件自身的数据更新  => 组件自身进入更新阶段
            (2) 父组件给子组件传递数据更新,  1. 父组件先进入更新阶段  => 在将模板解析为虚拟DOM 解析过程中,子组件也会进入更新阶段  !!

        
         Vue组件的生命周期(销毁阶段)
            (1) 组件自身被移除, 被移除之间会先进入销毁阶段 



    
    */


    Vue.component("LaowangClock",{
        template:`<div class="show-time">
            {{year}}-{{month}}-{{day}}  {{hour}}:{{min}}:{{sec}}
        </div>`,

        // 此写法有误 => 组件复用时, 使用共有一个data选项
        // data:{
        //     // now: new Date("2024-1-1 00:00:00"),
        //     now: new Date(),
        //     timer: null,
        // },

        // 为保证组件复用时数据分离(让每一个组件都有其自己独立的数据), 在组件初始化阶段会调用data函数,将函数返回的对象作为挂载的数据
        data:function(){
            return {
                // now: new Date("2024-1-1 00:00:00"),
                now: new Date(),
                timer: null,
            }
        },
        methods:{
            update(){
                clearInterval(this.timer);
                this.timer = setInterval(()=>{
                    this.now = new Date();
                },1000)
            },
            stop(){
                clearInterval(this.timer);
            }
        },
        computed:{
            year(){
                return this.now.getFullYear();
            },
            month(){
                // 月份参数: 0 - 11 
                // 实际月份 = 月份参数 + 1
                var month = this.now.getMonth() + 1
                return month.toString().padStart(2,"0");
            },
            day(){
                var day = this.now.getDate()
                return day.toString().padStart(2,"0");
            },
            hour(){
                var hour = this.now.getHours();
                return   hour.toString().padStart(2,"0");
            },
            min(){
                var min =this.now.getMinutes();
                return  min.toString().padStart(2,"0");
            },
            sec(){
                var sec = this.now.getSeconds();
                return   sec.toString().padStart(2,"0");
            },
            dateOption(){
                var year = this.now.getFullYear();
                var month = this.now.getMonth() + 1;
                var day = this.now.getDate();
                var hour = this.now.getHours();
                var min =this.now.getMinutes();
                var sec = this.now.getSeconds();
                return {
                    year:year,
                    month:month.toString().padStart(2,"0"),
                    day:day.toString().padStart(2,"0"),
                    hour:hour.toString().padStart(2,"0"),
                    min:min.toString().padStart(2,"0"),
                    sec:sec.toString().padStart(2,"0"),
                }
            }
        },
        beforeCreate () {
            console.log("时钟组件 beforeCreate");
        },
        created () {
            console.log("时钟组件 created");
        },
        beforeMount () {
            console.log("时钟组件 beforeMount");
        },
        mounted () {
            console.log("时钟组件 mounted");
            this.update();
        },

        // beforeUpdate () {
        //     console.log("时钟组件 beforeUpdate");
        // },
        
        // updated () {
        //     console.log("时钟组件 updated");
        // },

        beforeDestroy () {
            console.log("时钟组件 beforeDestroy");
            this.stop();
        },
        destroyed () {
            console.log("时钟组件 destroyed");
        } 
    })


   

    // 根组件 => 挂载到页面最外层中 (所有组件,都是根组件的子组件)
    var vm = new Vue({
        el:"#app",
        data:{
            count:1,
            isShow:false,
        },
        beforeCreate () {
            console.log("根组件 beforeCreate");
        },
        created () {
            console.log("根组件 created");
        },
        beforeMount () {
            console.log("根组件 beforeMount");
        },
        mounted () {
            console.log("根组件 mounted");
        }
    })



    


</script>
</html>